package com.weihua.modbus;

import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
import com.weihua.bo.MachineBo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * modbus 客户端
 * @author Administrator
 */
@Component
@Slf4j
public class ModbusClient {

    public static Map<String, ModbusMaster> masterMap = new ConcurrentHashMap<>();

    public ModbusMaster init(MachineBo bo){
        if(masterMap.get(bo.getMachinePk())!=null){
            if(masterMap.get(bo.getMachinePk()).isConnected()){
                try {
                    masterMap.get(bo.getMachinePk()).disconnect();
                    masterMap.remove(bo.getMachinePk());
                } catch (ModbusIOException e) {
                    log.error("断开PLC链接失败：{}",e.getMessage());
                }
            }
        }
        return this.getModbusMaster(bo);
    }

    private ModbusMaster getModbusMaster(MachineBo bo) {
        ModbusMaster master = null;
        try {
            TcpParameters tcpParameters = new TcpParameters();
            InetAddress address = InetAddress.getByName(bo.getIp());
            tcpParameters.setHost(address);
            tcpParameters.setKeepAlive(true);
            tcpParameters.setPort(bo.getPort());
            master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
            Modbus.setAutoIncrementTransactionId(true);
            masterMap.put(bo.getMachinePk(), master);
        }catch (Exception e){
            log.error("创建PLC链接失败：{}", e.getMessage());
        }
        return master;
    }

    public ModbusMaster get(MachineBo bo){
        ModbusMaster master = masterMap.get(bo.getMachinePk());
        if (master!=null && master.isConnected()){
            return master;
        }
        return init(bo);
    }
}
